package mongo

import (
	"context"
	"time"

	"github.com/mars/internal/pkg/options"
	"go.mongodb.org/mongo-driver/event"
	"go.mongodb.org/mongo-driver/mongo"
	mdbopts "go.mongodb.org/mongo-driver/mongo/options"
)

// NewClient 创建一个 Mongo client, opts 为连接 mongo 的基础条件
// event 用于拦截 mongo 请求的事件
func NewClient(opts *options.MongoOptions, event *event.CommandMonitor) (*mongo.Client, error) {
	clientOptions := &mdbopts.ClientOptions{Hosts: opts.Addrs}
	clientOptions.SetConnectTimeout(time.Duration(opts.ConnectTimeout) * time.Second)
	clientOptions.SetSocketTimeout(time.Duration(opts.SocketTimeout) * time.Second)
	clientOptions.SetServerSelectionTimeout(time.Duration(opts.SocketTimeout) * time.Second)
	clientOptions.SetMaxPoolSize(uint64(opts.PoolSize))
	clientOptions.SetMaxConnIdleTime(time.Duration(opts.MaxConnIdleTime) * time.Second)
	clientOptions.SetMonitor(event)

	if len(opts.Password)*len(opts.Username) != 0 {
		clientOptions.SetAuth(mdbopts.Credential{AuthSource: opts.Database, Username: opts.Username, Password: opts.Password})
	}
	return mongo.Connect(context.TODO(), clientOptions)
}

func PageFind(ctx context.Context, col *mongo.Collection, filter interface{},
	sink interface{}, opts ...*mdbopts.FindOptions) (total int64, err error) {

	if total, err = col.CountDocuments(ctx, filter); err != nil {
		return
	}
	var cursor *mongo.Cursor
	if cursor, err = col.Find(ctx, filter, opts...); err != nil {
		return
	}
	err = cursor.All(ctx, sink)
	return
}
